package cn.njupt.unionfind;

import cn.njupt.Student;
import cn.njupt.utils.Asserts;
import cn.njupt.utils.Times;

public class Test {
    static final int count = 1000000;
    public static void main(String[] args) {
//        testTime(new Quick_Union_Rank(count));
//        testTime(new Quick_Union_Size(count));
//        testTime(new Quick_Union_Rank_PathCompression(count));
//        testTime(new Quick_Union_Rank_PathSeparate(count));
//        testTime(new Quick_Union_Rank_PathHalfing(count));


        GenericUnionFind<Student> uf = new GenericUnionFind<>();
		Student stu1 = new Student(1, "jack");
		Student stu2 = new Student(2, "rose");
		Student stu3 = new Student(3, "jack");
		Student stu4 = new Student(4, "rose");
		uf.makeSets(stu1);
		uf.makeSets(stu2);
		uf.makeSets(stu3);
		uf.makeSets(stu4);

		uf.union(stu1, stu2);
		uf.union(stu3, stu4);

		uf.union(stu1, stu4);

		Asserts.test(uf.isSameSet(stu2, stu3));
//		Asserts.test(uf.isSameSet(stu3, stu4));
//		Asserts.test(!uf.isSameSet(stu1, stu3));
//        testTime1(new GenericUnionFind<>());
    }

    static void testTime1(GenericUnionFind<Integer> uf) {
        for (int i = 0; i < count; i++) {
            uf.makeSets(i);
        }
        uf.union(0, 1);
        uf.union(0, 3);
        uf.union(0, 4);
        uf.union(2, 3);
        uf.union(2, 5);

        uf.union(6, 7);

        uf.union(8, 10);
        uf.union(9, 10);
        uf.union(9, 11);

        Asserts.test(!uf.isSameSet(2, 7));

        uf.union(4, 6);

        Asserts.test(uf.isSameSet(2, 7));

        Times.test(uf.getClass().getSimpleName(), () -> {
            for (int i = 0; i < count; i++) {
                uf.union((int)(Math.random() * count),
                        (int)(Math.random() * count));
            }

            for (int i = 0; i < count; i++) {
                uf.isSameSet((int)(Math.random() * count),
                        (int)(Math.random() * count));
            }
        });
    }

    static void testTime(Union_Find uf) {
        uf.union(0, 1);
        uf.union(0, 3);
        uf.union(0, 4);
        uf.union(2, 3);
        uf.union(2, 5);

        uf.union(6, 7);

        uf.union(8, 10);
        uf.union(9, 10);
        uf.union(9, 11);

        Asserts.test(!uf.isSameSet(2, 7));

        uf.union(4, 6);

        Asserts.test(uf.isSameSet(2, 7));

        Times.test(uf.getClass().getSimpleName(), () -> {
            for (int i = 0; i < count; i++) {
                uf.union((int)(Math.random() * count),
                        (int)(Math.random() * count));
            }

            for (int i = 0; i < count; i++) {
                uf.isSameSet((int)(Math.random() * count),
                        (int)(Math.random() * count));
            }
        });
    }
}
